/* ====================================================================
 * (#)Header: ModelAction.java
 * (#)Revision: 
 * (#)Date Created: 2009-05-29
 * (#)Created By: Karol Wozniak
 * ====================================================================
 *
 * Copyright (c) 2007 karolak .  All rights reserved.
 *
 * ====================================================================
 * 
 * The software application represented here is the sole property of 
 * karolak. Its unauthorized utilization is expressly prohibited.
 * 
 * ====================================================================
 */
package com.karolak.web.saf.action;

import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.karolak.bean.PropertyComparator;
import com.karolak.service.Service;
import com.karolak.collection.CollectionUtils;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.interceptor.ScopedModelDriven;

/**
 * <code>ModelAction</code> is ...
 * 
 * @author <a href="mailto:kwozniak@hotmail.com">Karol Wozniak</a>
 */
public abstract class ModelAction<T, Id, S extends Service<T, Id>> extends ActionSupport implements Preparable, ScopedModelDriven<T>, SessionAware,
		ParameterAware, RequestAware {

	private static final long serialVersionUID = 1L;
	protected Log log = LogFactory.getLog(getClass().getName());

	private String scopeKey;
	private Map<String, Object> sessionMap;
	private Map<String, String[]> parameters;
	private Map<String, Object> requestMap;
	
	public Map<String, Object> getRequest() {
		return requestMap;
	}

	public void setRequest(Map<String, Object> requestMap) {
		this.requestMap = requestMap;
	}

	private S service;

	// === model === //
	private List<T> entities;

	// === abstract api === //
	public abstract Id getModelId();

	public abstract void setModel(T model);

	public abstract T getModel();

	public void prepare() throws Exception {
	}

	// === get/set === //
	public String getScopeKey() {
		return scopeKey;
	}

	public void setScopeKey(String scopeKey) {
		this.scopeKey = scopeKey;
	}

	@SuppressWarnings("unchecked")
	public void setSession(Map sessionMap) {
		this.sessionMap = sessionMap;
	}

	public Map<String, Object> getSession() {
		return sessionMap;
	}

	public Map<String, String[]> getParameters() {
		return parameters;
	}

	public void setParameters(Map<String, String[]> parameters) {
		this.parameters = parameters;
	}

	public S getService() {
		return service;
	}

	public void setService(S service) {
		this.service = service;
	}

	protected Comparator<T> createComparator(String... properties) {
		if (getModel() != null) {
			return new PropertyComparator<T>(getModel().getClass(), properties);
		}
		return null;
	}

	public List<T> getEntities() {
		return entities;
	}

	public void setEntities(List<T> entities) {
		this.entities = entities;
	}

	// === utility === //
	public void sort(List<T> entities, String... properties) {
		Comparator<T> comparator = createComparator(properties);
		sort(entities, comparator, properties);
	}

	protected void sort(List<T> entities, Comparator<T> comparator, String... properties) {
		CollectionUtils.sort(entities, comparator, properties);
	}

	public String[] getSortProperties() {
		return new String[] {};
	}
}
